package com.gopay.bis.service.bank.impl.ebank;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.ebank.PabB2bManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.PabConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.pab.ebank.PabB2bMessage;
import com.gopay.common.domain.bank.pab.ebank.PabOrderMessageRes;
import com.gopay.common.domain.bank.pab.ebank.PabQueryOrdersMessageRes;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankInteractRemoteService;

public class PabB2bBankServiceImpl implements BankInteractRemoteService {
	
	@Resource(name = "pabB2bManager")
	private PabB2bManager pabB2bManager;
	
	@Override
	public Result pay(BaseMessage base) {
		Result result = new Result(false);
		try {
			PabB2bMessage messageB2B = new PabB2bMessage();
			BeanUtils.copyProperties(base, messageB2B);
			messageB2B = (PabB2bMessage) pabB2bManager.sign(messageB2B);
			base.setBankOrderId(base.getOrderId());
			result.setDefaultModel(messageB2B);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6028);
		}
		return result;
	}
	@Override
	public Result bankBack(BaseMessage base) {
		Result result = new Result(false);
		try {
			PabOrderMessageRes messageB2B = new PabOrderMessageRes();
			BeanUtils.copyProperties(base, messageB2B);
			boolean flag = (Boolean) pabB2bManager.verify(messageB2B);
			result.setDefaultModel(flag);
			result.setSuccess(true);
			result.setModel("res", messageB2B);
			// 验签成功入账
			if (flag) {
				Map<String, String> param = new HashMap<String, String>();
				if (messageB2B.getCommitFlag().equals("0")) {
					// 通知后台地址入账					
					param.put("orderId", messageB2B.getOrderId());
					param.put("amt", messageB2B.getAmount().toString());
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "00");
					param.put("retCode", "00");
					param.put("retMsg", "验签成功");
					param.put("signData", messageB2B.getSignMessage());
					param.put("isFront", base.isFront()+"");
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(true);

				} else {
					// 通知后台地址该订单失败
					param.put("orderId", messageB2B.getOrderId());
					param.put("amt", messageB2B.getAmount().toString());
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "01");
					param.put("retCode", "01");
					param.put("retMsg", "验签失败");
					param.put("signData", messageB2B.getSignMessage());
					param.put("isFront", base.isFront()+"");
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(false);
				}
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;
	}
	
	@Override
	public Result query(BaseMessage base) {
		Result result = new Result(false);
		try {
			PabB2bMessage messageB2B = new PabB2bMessage();
			BeanUtils.copyProperties(base, messageB2B);
			PabQueryOrdersMessageRes res = (PabQueryOrdersMessageRes) pabB2bManager.query(messageB2B);
			result.setDefaultModel(res);
			result.setSuccess(true);
			if(BisPayCheckUtils.checkExternalOrderID(messageB2B.getOrderId())){
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", messageB2B.getOrderId());
				param.put("amount", messageB2B.getAmount().toString());
				if (res == null) {
					// 查询订单为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				if (!"0".equals(res.getStatus().trim())) {
					// 查询订单错误
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行订单查询交易异常");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				List orders = res.getOrders();
				if (orders == null) {
					// 能差到订单，表示银行肯定处理成功（只是不确定是否入账）。
					// 返回无数据可能银行处理失败，可能未收到订单，，可能未处理完，平台按处理中处理
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				if (orders.size() < 1) {
					// 通orders == null情况
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				PabOrderMessageRes order = (PabOrderMessageRes) orders.get(0);
				String commitFlag = order.getCommitFlag();// 结帐标记：0=未结帐，1=结帐中，2=已结帐，3=永不结帐，5=代表等待确认
				// 成功处理
				if (PabConstants.TRAN_SDB_DEAL_CHECKOUT.equals(commitFlag) || PabConstants.TRAN_SDB_DEAL_NO_CHECK.equals(commitFlag)) {
					param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
					param.put("returnMessage", "交易成功");
				}  else if(PabConstants.TRAN_SDB_DEAL_CHECK_IN.equals(commitFlag)){
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", PabConstants.TRAN_SDB_MESSAGE_CHECK_IN);
				}else if(PabConstants.TRAN_SDB_DEAL_DONT_CHECK.equals(commitFlag)){
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", PabConstants.TRAN_SDB_MESSAGE_DONT_CHECK);
				}else if(PabConstants.TRAN_SDB_DEAL_TOBE_CONFIRMED.equals(commitFlag)){
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", PabConstants.TRAN_SDB_MESSAGE_TOBE_CONFIRMED);
				}
				else {
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", PabConstants.TRAN_SDB_MESSAGE_NO_CHECK);
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6032);
		}
		return result;
	}
	@Override
	public Result refund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result dayend(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result queryBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}
    @Override
    public Result refundBack(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public Result refundQuery(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }
	@Override
	public Result sendBankRefund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

}
